package com.wushijia.java8.lambda;

import static java.util.Comparator.comparing;
import static java.util.Comparator.comparingInt;

import com.wushijia.model.User;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * description:行为参数化：Lamdba和方法引用
 *
 * @author yang
 * @date 2018/4/25 21:21
 */
public class Chapter1 {

  public static void main(String[] args) {
    //第一种方法
    List<User> userList = new ArrayList<>();
    userList.sort(new UserComparator());
    //第二种方法：使用匿名类
    userList.sort(new Comparator<User>() {
      @Override
      public int compare(User o1, User o2) {
        return Integer.compare(o1.getAge(), o2.getAge());
      }
    });
    //第三种方法：使用lambda表达式
    userList.sort((User o1, User o2) -> Integer.compare(o1.getAge(), o2.getAge()));

    //省略类型，java编译器可以根据Lamdba出现的上下文推断Lamdba表达式参数的类型
    userList.sort((user1, user2) -> Integer.compare(user1.getAge(), user2.getAge()));

    //通过Comparator的静态辅助方法comparing来比较，他会生成一个Compatator对象
    userList.sort(Comparator.comparing((user) -> user.getAge()));
    //需导入 import static java.util.Comparator.comparing;
    userList.sort(comparing((user) -> user.getAge()));

    //方法引用：替代那些转发参数的Lambda表达式的语法糖
    userList.sort(Comparator.comparingInt(User::getAge));
    userList.sort(comparingInt(User::getAge));

    //方法引用实例
    String s = "111";
    int i = Integer.parseInt(s);

    //构造函数引用
    //Supplier:返回一个对象，不接受参数，无参构造函数
    Supplier<User> userSupplier = User::new;
    User user1 = userSupplier.get();

    Function<Integer, User> userFunction = User::new;
    User user2 = userFunction.apply(25);

    TriFunction<String, String, Integer, User> userTriFunction = User::new;
    userTriFunction.apply("侯阳阳", "男", 25);

    //复合lambda表达式
    //1、比较器复合之逆序
    userList.sort(comparing(User::getAge).reversed());//按照年龄递减排序
    //2、比较器复合之比较器链
    userList.sort(comparing(User::getAge).reversed().thenComparing(User::getName));//按照年龄递减排序后再按照名字排序

    //谓词复合:从左向右确定优先级
    Predicate<User> youngUser = user -> user.getAge() > 20;
    Predicate<User> notYoungUser = youngUser.negate();
    Predicate<User> notYoungMan = notYoungUser.and(user -> "男".equals(user.getSex()));
    Predicate<User> notYoungManOrWoman = notYoungMan.or(user -> "女".equals(user.getSex()));

    //函数复合
    Function<Integer, Integer> f = x -> x + 1;
    Function<Integer, Integer> g = x -> x * 2;
    Function<Integer, Integer> h = f.andThen(g);//g(f(x))
    int result = h.apply(2);
    System.out.println(result);

    Function<Integer,Integer> h2 = f.compose(g);//f(g(x)),将g的结构作为参数传给f
    System.out.println(h2.apply(2));

  }

  private static class UserComparator implements Comparator<User> {

    @Override
    public int compare(User o1, User o2) {
      return Integer.compare(o1.getAge(), o2.getAge());
    }
  }

}
